using Engine.DynamicObjectManager;
using Engine.FileFormats3D;
using Engine.Graphics;
using Engine.Shape;
using Engine.TrafficHelpers;
using Scenario_Editor.Addin.Traffic;
using Scenario_Editor.Tools;
using SharpDX;
using System.Collections.Generic;
using System.IO;

namespace Scenario_Editor.Addin
{
    public interface IScenarioEditorMethods
    {
        #region Public Methods

        void ActivatePanel(int nOfRoadsFromStreetpoint);

        PositionsAndAngles CalculatePositionsAndAngles(List<Vector3> Tangents, object PropertiesFromRoads);

        Mesh3dData CreateCrossroadMesh(Vector3 centerOfCross,
                                           object propertiesForCP,
                                           List<decimal> anglesFromStreets,
                                           List<Vector3> startPointsFromStreets);

        Shapes CreateCrossroadShape(Vector3 centerOfCross,
                                           object propertiesForCP,
                                           List<decimal> anglesFromStreets,
                                           List<Vector3> startPointsFromStreets);

        Mesh3dData CreateRoadmesh(
                                   Vector3[] splinePoints,//Middle line
                                   decimal anglePointOne,// Angles from start and End point
                                   decimal anglePointTwo,
                                   object PropertiesForBothStreets);

        Shapes CreateShape(
                                   Vector3[] splinePoints,
                                   decimal anglePointOne,
                                   decimal anglePointTwo,
                                   object PropertiesForStreet
                                   );

        List<BaseObject> GetDynamicObjects(
                                   Vector3[] splinePoints,
                                   decimal anglePointOne,
                                   decimal anglePointTwo,
                                   object PropertiesForStreet
                                   );

        List<BaseObject> GetDynamicObjectsCrossroad(
                                    Vector3 centerOfCross,
                                    object propertiesForCP,
                                    List<decimal> anglesFromStreets,
                                    List<Vector3> startPointsFromStreets
                                    );

        string GetPlugInName();

        // ~~~~~~~~~~~~~~~~~~~~ Properties Exchange ~~~~~~~~~~~~~~~
        object GetProperties();

        object GetPropertiesForCrossroad(int numberOfAdjoingStreets);

        // ~~~~~~~~~~~~~~~~~~~~~~~Traffic ~~~~~~~~~~~~~~~~~~~~~~~~~
        WR2Traffic GetTrafficProperties(object roadProperties);

        CrossroadTraffic[] GetTrafficPropertiesCrossroad(Vector3 centerOfCross,
                                           object propertiesForCP,
                                           List<decimal> anglesFromStreets,
                                           List<Vector3> startPointsFromStreets);

        void GiveTexturesPaths(MaterialManager materialManager);

        bool HasPropertiesChanged();

        object LoadCrossroadProperties(BinaryReader reader);

        object LoadRoadProperties(BinaryReader reader);

        void OnAddinChanged(Engine.AddinManager.IAddin gameDll, Scenario_Editor.AddinManager.IAddinScenarioEditor sceneryEditorAddin);

        void OnSceneryEditorClosing();

        void OnTerrainChange(ITerrain newTerrain);

        void SaveCrossroadProperties(BinaryWriter writer, object CrossroadProperties);

        void SaveRoadProperties(BinaryWriter writer, object RoadProperties);

        void SetProperties(object properties);

        void SetPropertiesForCrossroad(object properties);

        void SetTrafficProperties(WR2Traffic properties);

        void SetTrafficPropertiesCrossroad(CrossroadTraffic[] propertiesForTraffic);

        #endregion Public Methods
    }

    public struct PositionsAndAngles
    {
        #region Private Fields

        private decimal[] angles;
        private List<Vector3> positions;

        #endregion Private Fields

        #region Public Constructors

        public PositionsAndAngles(decimal[] angles, Vector3[] positions)
        {
            this.angles = new decimal[angles.Length];
            angles.CopyTo(this.angles, 0);
            this.positions = new List<Vector3>(positions);
        }

        #endregion Public Constructors

        #region Public Properties

        public decimal[] Angles
        {
            get
            {
                return this.angles;
            }
        }

        public List<Vector3> Positions
        {
            get
            {
                return this.positions;
            }
        }

        #endregion Public Properties
    }
}